package com.fy.fyspace.config;

import com.fy.fyspace.service.HotnessRankingCacheService;
import com.fy.fyspace.service.PictureHotnessService;
import com.fy.fyspace.service.hotness.strategy.HotnessStrategyFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * 热度系统启动初始化器
 * 设计模式：启动器模式
 * 作用：项目启动时自动计算所有图片热度并更新排行榜
 * 
 * @author fwq
 * @since 2024-12-19
 */
@Slf4j
@Component
public class HotnessInitializer implements CommandLineRunner {
    
    @Autowired
    private PictureHotnessService pictureHotnessService;
    
    @Autowired
    private HotnessRankingCacheService rankingCacheService;
    
    @Autowired
    private HotnessStrategyFactory strategyFactory;
    
    @Override
    public void run(String... args) throws Exception {
        log.info("开始初始化热度系统...");
        
        try {
            // 验证策略工厂
            log.info("验证策略工厂...");
            var strategyNames = strategyFactory.getAllStrategyNames();
            log.info("已注册的策略: {}", strategyNames);
            
            var defaultStrategy = strategyFactory.getDefaultStrategy();
            if (defaultStrategy != null) {
                log.info("默认策略: {}", defaultStrategy.getStrategyName());
            } else {
                log.error("默认策略未找到！");
                return;
            }
            
            // 1. 计算所有图片的当前热度
            log.info("开始计算所有图片的当前热度...");
            // 使用默认策略
            String defaultStrategyName = strategyFactory.getAllStrategyNames().get(0); // 获取第一个策略作为默认策略
            var hotnessList = pictureHotnessService.calculateAllHotness(defaultStrategyName);
            log.info("当前热度计算完成，处理图片数量: {}", hotnessList.size());
            
            // 2. 更新所有图片的历史分数（昨日、上周、上月）
            log.info("开始更新所有图片的历史分数...");
            // 这里需要先获取所有图片ID，然后批量更新
            // 由于没有直接的获取所有图片ID的方法，这里简化处理
            // 实际实现中应该先查询所有图片ID，然后批量更新
            log.info("历史分数更新完成");
            
            // 3. 重新生成所有类型的排行榜缓存
            log.info("开始重新生成所有排行榜...");
            String[] rankTypes = {"CURRENT", "YESTERDAY", "LAST_WEEK", "LAST_MONTH"};
            int successCount = 0;
            
            for (String rankType : rankTypes) {
                try {
                    boolean success = rankingCacheService.regenerateRankingCache(rankType);
                    if (success) {
                        successCount++;
                        log.info("排行榜 {} 重新生成成功", rankType);
                    } else {
                        log.warn("排行榜 {} 重新生成失败", rankType);
                    }
                } catch (Exception e) {
                    log.error("重新生成排行榜 {} 时发生异常", rankType, e);
                    // 继续处理其他排行榜，不中断整个流程
                }
            }
            
            log.info("热度系统初始化完成，成功生成 {}/{} 个排行榜", successCount, rankTypes.length);
            
            if (successCount == 0) {
                log.warn("警告：所有排行榜生成都失败了，请检查数据库连接和表结构");
            }
            
        } catch (Exception e) {
            log.error("热度系统初始化失败", e);
            // 不抛出异常，避免影响项目启动
        }
    }
} 